<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>javascript中的函数</title>
        <style type="text/css">
            *{padding: 0; padding: 0;}
        </style>
    </head>
    <body>

        <script type="text/javascript">
            // 通过function定义函数
                // 命名方式（声明式）
            function f2(){
                alert();
            }
                // 匿名方式 （引用式函数定义/函数表达式）
            var f1 = function(){
                alert();
            }

            function dwn(s){
                document.write(s + '<br />');
            }

            function t1(){
                dwn('t1');
            }
            t1();
            function t1(){ // 
                dwn('new t1');
            }
            t1();
            t1 = function(){
                dwn('new new t1');
            }
            t1();

            // call, apply 区别
            var func1 = function(arg1, arg2){
                alert('This is func1');
            };

            // 函数调用的三种方式
            /*
            obj.myFunc();
            myFunc.call(obj, arg);
            myFunc.apply(obj, [arg1, arg2, ...]);
            */

            // call this用来指定上下文 参数按顺序传进去 参数的数量明确知道时用call
            //func1.call(this, arg1, arg2);

            // apply  this用来指定上下文 参数以数组形式传进去  参数的数量不确定用apply将参数push进数组传参 
            // 函数内部可用arguments这个数组遍历所有的参数
            //func1.apply(this, [arg1, arg2]); 


            /*
             *当一个object没有某个方法，但是其他的有，我们可以借助call或apply用其它对象的方法来操作。
             */
            function cat(){}
            cat.prototype = {
                food : 'fish',
                say : function(){
                    alert('I like this ' + this.food);
                }
            };

            var blackCat = new cat;
            blackCat.say();

            var whiteDog = {food : 'bone'};
            blackCat.say.call(whiteDog);

            whiteDog.say();

            // 通过document.getElementsByTagName选择的dom 节点是一种类似array的array。它不能应用Array下的push,pop等方法。我们可以通过：
            var domNodes =  Array.prototype.slice.call(document.getElementsByTagName("*"));
            // 这样domNodes就可以应用Array下的所有方法了。
            
            
            // js中的属性
            function test(){
                var w = '0000'; // 私有属性
                this.x = '1111'; // 公有属性
            }
            test.y = '2222'; // 私有属性 类属性 无法通过对象访问
            test.prototype.z = '3333'; // 公有属性
            var test2 = new test();
            console.log(test2);
            // console.log(w);
            console.log(test2.w); // undefined
            console.log(test2.x); // 1111
            console.log(test2.y); // undefined
            console.log(test.y); // 2222
            console.log(test2.z); // 3333

            delete(test2.x);
            delete(test2.z);

            console.log(test2.x); // undefined
            console.log(test2.z); // 3333
            
            
            
            
            /*------------------------------*/
            function Poylygon(){
                var m_points = [];
                m_points = Array.apply(m_points, arguments);
            
                // 利用prototype创建对象的副本 来保证对象的可读 比copy对象效率高
                function GETTER(){};
                GETTER.prototype = m_points[0];
                this.firstPoint = new GETTER();

                // this.firstPoint = m_points[0];

                this.length = {
                    valueOf : function(){
                        return m_points.length;
                    },
                    toString : function(){
                        return m_points.length;
                    }
                };

                this.add = function(){
                    m_points.push.apply(m_points, arguments);
                };

                this.getPoint = function(index){
                    return m_points[index];
                };

                this.setPoint = function(index, point){
                    if(m_points[index] == null){
                        m_points[index] = point;
                    }else{
                        m_points[index].x = point.x;
                        m_points[index].y = point.y;
                    }
                };
            }

            // 构建一个三角形
            var p = new Poylygon({x : 1, y :2}, {x : 2, y : 4}, {x : 2, y : 6});

            console.log(p.getPoint(0));
            console.log(p.length.toString());
            console.log(p.firstPoint);
            p.add({x : 2, y :8});
            console.log(p.getPoint(3));
            p.setPoint(0, {x : 1, y : 1});
            console.log(p.getPoint(0));
            console.log(p);


            delete p.firstPoint.x;
            console.log(p.getPoint(0));
        </script>
    </body>
</html>